package is.bean.entity;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.ejb.EJBException;
import javax.ejb.EntityContext;
import javax.naming.InitialContext;
import javax.sql.DataSource;

/**
 *
 * @author aspr0
 */
public abstract class BeanRoutines
{
    protected static final String jdbcResource = "jdbc/isbd";
    protected EntityContext context;
    protected DataSource dataSource;
    protected boolean modified = false;
    protected String tableName;

    /**
     * @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)
     */
    public void setEntityContext(EntityContext aContext)
    {
        context = aContext;
        try
        {
            InitialContext ic = new InitialContext();
            dataSource = (DataSource) ic.lookup(jdbcResource);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * @see javax.ejb.EntityBean#unsetEntityContext()
     */
    public void unsetEntityContext()
    {
        context = null;
    }

    /**
     * @see javax.ejb.EntityBean#ejbLoad()
     */
    public void ejbLoad()
    {
        try
        {
            loadData();
        }
        catch (SQLException ex)
        {
            throw new EJBException(ex);
        }
    }

    /**
     * @see javax.ejb.EntityBean#ejbStore()
     */
    public void ejbStore()
    {
        try
        {
            storeData();
        }
        catch (SQLException ex)
        {
            throw new EJBException(ex);
        }
    }

    /**
     * On next .nextval call sequence seqName will produce shiftTo value
     *
     * @param seqName
     * @param shiftTo
     * @throws SQLException
     */
    protected boolean shiftSequence(String seqName, int shiftTo) throws SQLException
    {
        Connection connection = null;
        PreparedStatement statement = null;
        CallableStatement callableStatement = null;
        ResultSet resultSet = null;
        boolean shifted = false;
        try
        {
            connection = dataSource.getConnection();
            String sql = "select %1$s.nextval as currval from dual"; //todo one value lost here :(
            sql = String.format(sql, seqName);
            statement = connection.prepareStatement(sql);
            resultSet = statement.executeQuery();
            resultSet.next();
            int currVal = resultSet.getInt("currval");
            int incByVal = shiftTo - currVal - 1;
            if (incByVal > 0)
            {
                sql =
                        "declare "
                        + "devnull int; "
                        + "begin "
                        + "execute immediate ('alter sequence %1$s increment by %2$s'); "
                        + "execute immediate ('select %1$s.nextval from dual') into devnull; "
                        + "execute immediate ('alter sequence %1$s increment by 1'); "
                        + "end;";

                sql = String.format(sql, seqName, incByVal);
                callableStatement = connection.prepareCall(sql);
                //                callableStatement.setInt(1, incByVal);
                callableStatement.execute();
                shifted = true;
            }
        }
        finally
        {
            if (statement != null)
            {
                statement.close();
            }
            if (callableStatement != null)
            {
                statement.close();
            }
            if (connection != null)
            {
                connection.close();
            }
            if (resultSet != null)
            {
                resultSet.close();
            }
        }
        return shifted;
    }

    protected abstract void loadData() throws SQLException;

    protected abstract void storeData() throws SQLException;
}
